#include "HiranipraShared.h"

#include "HCM/IComponent.h"

#ifndef _SHARED_HCM_COMPONENT_FACTORY_H_
#define _SHARED_HCM_COMPONENT_FACTORY_H_

#define DECLARE_COMPONENT_TYPE( ix ) static const HCMID ix##TypeID
#define REGISTER_COMPONENT_IMPL( ix, cx, implId ) AutoComponentFactory<cx> cx##Factory( ix##TypeID, implId, L###cx );

#define REFERENCE_COMPONENT( ns, cx ) extern AutoComponentFactory<ns::cx> cx##Factory;

#define COMPONENT_IMPL( cx ) &( cx##Factory )
#define COMPONENT_TYPE( ix ) ix##TypeID

namespace Hiranipra {
	namespace HCM {
		
		class ComponentFactory
		{
		public:
			HCMID		TypeID;
			HCMID		ImplID;
			wstring		Name;

			ComponentFactory( HCMID typeId, HCMID implId, wstring name ) :
				TypeID( typeId ), ImplID( implId ), Name( name )
			{
			}
			
			virtual IComponent* Allocate() const = 0;
			template<class T> T* Allocate() const
			{
				return ( T* )this->Allocate();
			}
		};

		template <class T> class AutoComponentFactory : public ComponentFactory
		{
		public:
			AutoComponentFactory( HCMID typeId, HCMID implId, wstring name ) :
				ComponentFactory( typeId, implId, name )
			{
			}

			virtual IComponent* Allocate() const { return ( IComponent* )new T(); }
		};

	}
}

#endif // _SHARED_HCM_COMPONENT_FACTORY_H_
